package com.gitee.dolt.mail.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.mail.MailAccount;
import cn.hutool.extra.mail.MailException;
import cn.hutool.extra.mail.MailUtil;
import com.gitee.dolt.core.util.SpringUtils;
import com.gitee.dolt.mail.entity.MailSendLogDTO;
import com.gitee.dolt.mail.event.MailSendLogEvent;
import com.gitee.dolt.mail.properties.MailProperties;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author LYH
 */
@Slf4j
public class MailService {

    private static final Map<String, MailAccount> MAIL_ACCOUNTS = new HashMap<>();

    private static final String DEFAULT_MAIL_ID = "default";

    public MailService(MailProperties mailProperties) {
        List<MailProperties.MailConfig> configs = mailProperties.getConfigs();
        if (CollUtil.isEmpty(configs)) {
            throw new MailException("缺少邮件配置，dolt.mail.configs");
        }
        MailAccount defaultMailAccount = null;
        for (int i = 0; i < configs.size(); i++) {
            MailProperties.MailConfig mailConfig = configs.get(i);
            String id = mailConfig.getId();
            String host = mailConfig.getHost();
            int port = mailConfig.getPort();
            String from = mailConfig.getFrom();
            String user = mailConfig.getUser();
            String pass = mailConfig.getPass();
            boolean sslEnable = mailConfig.isSslEnable();
            boolean isAuth = mailConfig.isAuth();
            if (StrUtil.isEmpty(from)) {
                from = user;
            }
            MailAccount mailAccount = new MailAccount().setHost(host).setPort(port).setFrom(from).setUser(user)
                    .setPass(pass).setAuth(isAuth).setSslEnable(sslEnable);
            MAIL_ACCOUNTS.put(id, mailAccount);
            if (i == 0) {
                defaultMailAccount = mailAccount;
            }
        }
        if (!MAIL_ACCOUNTS.containsKey(DEFAULT_MAIL_ID)) {
            MAIL_ACCOUNTS.put(DEFAULT_MAIL_ID, defaultMailAccount);
        }
    }

    public MailAccount getMailAccount(String mailId) {
        MailAccount mailAccount = MAIL_ACCOUNTS.get(mailId);
        return mailAccount;
    }

    public boolean sendEmail(String to, String subject, String content) {
        return sendEmail(DEFAULT_MAIL_ID, CollUtil.newArrayList(to), null, null, subject, content, false, null);
    }

    public boolean sendEmail(Collection<String> tos, Collection<String> ccs, Collection<String> bccs, String subject,
                             String content, boolean isHtml, File[] files) {
        return sendEmail(DEFAULT_MAIL_ID, tos, ccs, bccs, subject, content, isHtml, files);
    }

    /**
     * @param mailId  邮件配置id
     * @param tos     接收者
     * @param ccs     抄送
     * @param bccs    密送
     * @param subject 主题
     * @param content 内容
     * @param isHtml  是否html
     * @param files   文件
     * @return
     */
    public boolean sendEmail(String mailId, Collection<String> tos, Collection<String> ccs,
                             Collection<String> bccs, String subject, String content, boolean isHtml, File[] files) {
        MailSendLogDTO mailSendLogDTO = new MailSendLogDTO()
                .setRecipients(tos)
                .setCcs(ccs)
                .setBcss(bccs)
                .setContent(content)
                .setSubject(subject)
                .setMailId(mailId)
                .setHtml(isHtml);
        boolean flag = false;
        try {
            MailAccount mailAccount = getMailAccount(mailId);
            if (mailAccount == null) {
                throw new MailException("缺少邮件配置，mailId：{}", mailId);
            }
            mailSendLogDTO.setBeginDate(LocalDateTime.now()).setFrom(mailAccount.getFrom());
            MailUtil.send(mailAccount, tos, ccs, bccs, subject, content, isHtml, files == null ? new File[0] : files);
            mailSendLogDTO.setSentDate(LocalDateTime.now());
            flag = true;
        } catch (MailException e) {
            mailSendLogDTO.setResult(e.getMessage());
        } catch (Exception e) {
            mailSendLogDTO.setResult("系统异常");
        }
        mailSendLogDTO.setSuccess(flag);
        SpringUtils.publishEvent(new MailSendLogEvent(mailSendLogDTO));
        return flag;
    }
}
